package com.feihong.txgw.utils.glidehttps;

import android.support.annotation.NonNull;
import android.util.Log;

import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.HttpException;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.util.ContentLengthInputStream;
import com.bumptech.glide.util.Preconditions;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;


/**
 * Fetches an {@link InputStream} using the okhttp library.
 */
public class OkHttpStreamFetcher implements DataFetcher<InputStream>, Callback {
    private final GlideUrl mGlideUrl;
    private final Call.Factory mFactory;
    private volatile Call mCall;

    private DataCallback<? super InputStream> mCallback;
    private final static String TAG = "通讯顾问";
    public OkHttpStreamFetcher(Call.Factory factory, GlideUrl url) {
        this.mFactory = factory;
        this.mGlideUrl = url;
    }

    @Override
    public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
        Request.Builder requestBuilder = new Request.Builder().url(mGlideUrl.toStringUrl());
        for (Map.Entry<String, String> headerEntry : mGlideUrl.getHeaders().entrySet()) {
            String key = headerEntry.getKey();
            requestBuilder.addHeader(key, headerEntry.getValue());
        }

        mCallback = callback;
        Request request = requestBuilder.build();
        mCall = mFactory.newCall(request);
        mCall.enqueue(this);
    }

    @Override
    public void cleanup() {
        if (mStream != null) {
            try {
                mStream.close();
            } catch (IOException e) {
                // Ignored
            }
        }
        if (mResponseBody != null) {
            mResponseBody.close();
        }
    }

    @Override
    public void cancel() {
        // TODO: call cancel on the client when this method is called on a background thread. See #257
    }

    @NonNull
    @Override
    public Class<InputStream> getDataClass() {
        return InputStream.class;
    }

    @NonNull
    @Override
    public DataSource getDataSource() {
        return DataSource.REMOTE;
    }

    @Override
    public void onFailure(@NonNull Call call, @NonNull IOException e) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "OkHttp failed to obtain result", e);
        }

        mCallback.onLoadFailed(e);
    }

    private InputStream mStream;
    private ResponseBody mResponseBody;
    @Override
    public void onResponse(@NonNull Call call, @NonNull Response response) {
        Log.i(TAG, "onResponse: ");
        mResponseBody = response.body();
        if (response.isSuccessful()) {
            long contentLength = Preconditions.checkNotNull(mResponseBody).contentLength();
            mStream = ContentLengthInputStream.obtain(mResponseBody.byteStream(), contentLength);
            mCallback.onDataReady(mStream);
        } else {
            mCallback.onLoadFailed(new HttpException(response.message(), response.code()));
        }
    }
}
